﻿
using System;
using System.Windows.Forms;

/**Class: OperationDay
 * @author Sara Tuohy
 * @version 1.0
 * Course : ITEC 4860 Spring, 2012
 * Written: March, 2012
 * 
 * This class stores the details of an OperationDay
 * Purpose: a business week has days Sunday - Saturday.  The details of start time, end time, the related isClosed?
 * are stored in an OperationDay.
 * 
 * Update 04/12/2012: saving the hours of operation was allocating a new operation day and losing all previously saved data
 * updated to add setters for start time, end time, start IDX and end IDX so those can update without clearing numPerSlot info
 */
public class OperationDay
{
    /**
     * "Sunday", "Monday", ... , "Saturday"                             */
    private string day;
    /**
     * Times are stored in strings of length 5: HH:MM                   */
    private string startTime;
    /**
     * Times are stored in strings of length 5: HH:MM                   */
    private string endTime;
    /**
     * In case the increment changes                                    */
    private const double increment = 0.5;
    /**
     * Indices make communicating data easier                           */
    private int startIdx;
    /**
     * Indices make communicating data easier                           */
    private int endIdx;
    /**
     * Time slots = # hours open * increment   */
    private int numberOfStaffedTimeSlots;
    /**
     * Time slots in a work (Operation) day     */
    private const int NUMBER_SLOTS_PER_DAY = 48;
    /**
     * How many employees are needed for each time increment    */
    private int[] numPerSlot;
    /**
     * All 48 slots with zeroes in the closed hours         */
    private int[] numPerAllTimeSlots;
    /**
     * Will eventually be needed by the schedule builder algorithm */
    private double totalWorkHours;
    /**
     * Presumed closed unless end time is later than start time      */
    bool isClosed;


    /**Method: OperationDay
     * Constructs OperationDay
     * constructor accepts the day of the week, start and end times for that day
     * @param dayOfWeek - string SUN, MON, etc.
     * @param startOfDay - start time in HH:MM string format
     * @param endOfDay - end time in HH:MM string format
     * @param startArrayIndex - int index of start time in Array of Times
     * @param endArrayIndex - int index of end time in Array of Times
     */
    public OperationDay(string dayOfWeek, string startOfDay, string endOfDay, int startArrayIndex, int endArrayIndex)
    {
        day = dayOfWeek;
        startTime = startOfDay;
        endTime = endOfDay;
        startIdx = startArrayIndex;
        endIdx = endArrayIndex;
        numberOfStaffedTimeSlots = (endIdx - startIdx);
        if (numberOfStaffedTimeSlots > 0)
        {
            numPerSlot = new int[numberOfStaffedTimeSlots];
            numPerAllTimeSlots = new int[NUMBER_SLOTS_PER_DAY];
        }
        else isClosed = true;
    }

    /**Method: isOpen
     * @return bool true if open
     */
    public bool isOpen()
    {
        return !isClosed;
    }

    /**Method: getStartIndex
     * @return int startIndex
     */
    public int getStartIndex()
    {
        return startIdx;
    }

    /**Method: setStartIndex
     * @param int startIndex new value
     */
    public void setStartIndex(int newStartIdx)
    {
        startIdx = newStartIdx;
    }


    /**Method: getEndIndex
     * @return int endIndex
     */
    public int getEndIndex()
    {
        return endIdx;
    }

    /**Method: setEndIndex
     * @param int newEndIndex
     */
    public void setEndIndex(int newEndIdx)
    {
        endIdx = newEndIdx;
    }

    /**Method: getNumPerTimeSlot
     * returns the values set by the manager
     * Purpose: return the range for the Combo boxes,
     * only covers the hours of operation.
     * @return int[] number needed for each open time slot
     */
    public int[] getNumPerTimeSlot()
    {
        return numPerSlot;
    }

    /**Method: getStaffPerTimeSlot
     * returns staff required values but omitting the last slot (closing time)
     * Purpose: for use by the schedule generation algorithm
     * @return int[] number needed without the slot for the end time
     */
    public int[] getStaffPerTimeSlot()
    {
        int[] staffNeeded = new int[numPerSlot.Length - 1];
        for (int i = 0; i < staffNeeded.Length; i++)
        {
            staffNeeded[i] = numPerSlot[i];
        }
        return staffNeeded;
    }

    /**Method: setNumPerHour
     * copy the input values into the numPerSlot array
     * Purpose: this is the range used by the ComboBoxes, 
     * only includes the times the business is open
     * @param int[] empsNeeded sets local numPerSlot
     */
    public void setNumPerTimeSlot(int[] empsNeeded)
    {
        numPerSlot = empsNeeded;
    }

    /**Method: getNumPerAllTimeSlots
     * returns the values set by the manager
     * Purpose: to return the all day array,
     * ready for storage in the DB
     * @return int[] numPerAllTimeSlots all day array
    */
    public int[] getNumPerAllTimeSlots()
    {
        return numPerAllTimeSlots;
    }

    public string getDayName()
    {
        return day;
    }

    /**Method: setNumPerAllTimeSlots
     * Receives the values from the DB and sets up the all day array
     * Purpose: restore values from the data base in case the manager
     * exercises the option to modify the values
     * Note: the resulting array is of length 48, with (default)
     * zeroes in all of the time slots that the business is closed ...
     * @param int[] empsNeeded  
     */
    public void setNumPerAllTimeSlots(int[] empsNeeded)
    {
        numPerAllTimeSlots = empsNeeded;
    }

    /**Method: copyToAllDayArray
     * Copy the input values for the open hours into the numPerAllSlot array
     * Purpose: make values available to DB save effort
     * Note: the resulting array is of length 48, with (default)
     * zeroes in all of the time slots that the business is closed ...
     */
    public void copyToAllDayArray()
    {
        Array.Copy(numPerSlot, 0, numPerAllTimeSlots, startIdx, numberOfStaffedTimeSlots);
        //staffReqSet = true;
    }


    /**Method: copyToOpenTimeSlots
     * Copy the values from the AllDayArray to the open (staffed) hours
     * Purpose: to load the values from the data base
     */
    public void copyToOpenTimeSlots()
    {
        Array.Copy(numPerAllTimeSlots, startIdx, numPerSlot, 0, numberOfStaffedTimeSlots);
    }

    /**Method: staffRequirementsHaveBeenSet
     * Verifies values set
     * Purpose: to prevent calling an uninitialized array
     */
    public bool staffRequirementsHaveBeenSet()
    {
        return true;
    }

    /**Method: getTotalWorkHours
     * Calculates the total man hours: Sum(each slot * increment * number needed)
     * Will be used by the schedule generation algorithm
     * @return double total man hours needed for the work week
     */
    public double getTotalWorkHours()
    {
        int count = 0;
        if ((totalWorkHours == 0) && (numPerSlot != null))
        {
            for (int i = 0; i < numPerSlot.Length; i++)
            {
                count += numPerSlot[i];
            }
            totalWorkHours = count * increment;
        }
        return totalWorkHours;
    }

    /**Method: getSTart
     * Returns the time the work day begins
     * @return string startTime (HH:MM)
     */
    public string getStart()
    {
        return startTime;
    }

    /**Method: setStart
     * Sets the time the work day begins
     * @param string newStartTime (HH:MM)
     */
    public void setStart(string newStartTime)
    {
        startTime = newStartTime;
    }

    /**Method: getEnd
     * Returns the time the work day ends
     * @return string endTime (HH:MM)
     */
    public string getEnd()
    {
        return endTime;
    }

    /**Method: setEnd
     * Sets the time the work day ends
     * @param string newEndTime (HH:MM)
     */
    public void setEnd(string newEndTime)
    {
        endTime = newEndTime;
    }

    //for debug and display purposes
    /**Method: toString
     * Displays the day's information
     * Purpose: for diagnostic displays
     */
    public string toString()
    {
        string dayValues = this.day + " Start time: " + this.startTime + " End time: " + this.endTime;
        return dayValues;
    }
}